#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <linux/videodev2.h>
#include "../inc/cbb_enc_api.h"
#include "../inc/cbb_camera_api.h"

#define CAMERA_DEV_PATH "/dev/video44"
#define MPI_TEST_OUTPUT_FILE_JPEG_DIR "/userdata/tzw/demo/test/jpeg_tmp"
#define MPI_TEST_OUTPUT_FILE_H264 "/userdata/tzw/demo/test/h264_tmp/camera_1.h264"

static int jpeg_index = 0;
int process_jpeg(const CbbEncoderRes_t jpeg_frame)
{
	char jpeg_path[256] = {0};
    snprintf(jpeg_path, sizeof(jpeg_path)-1, "%s/jpeg_%d.jpeg", MPI_TEST_OUTPUT_FILE_JPEG_DIR, jpeg_index);

	if (jpeg_frame.len > 0)
	{
		FILE *fp_input = fopen(jpeg_path, "w+b");
        if (!fp_input) {
            printf("Can not open input file[%s] \r\n", jpeg_path);
			return -1;
        }

		int write_len = fwrite(jpeg_frame.res_data, 1, jpeg_frame.len, fp_input);
		if (write_len < 0){
			printf("ret = %d\r\n", write_len);
			return -1;
		}
		jpeg_index++;
	}

	return 0;
}

int process_h264(FILE *file, CbbEncoderRes_t h264_frame)
{
	if (file == NULL){
		return -1;
	}

	int write_len = fwrite(h264_frame.res_data, 1, h264_frame.len, file);
	if (write_len < 0){
		printf("ret = %d\r\n", write_len);
		return -1;
	}

	return 0;
	
}

int save_raw(CbbCameraFrame_t raw_frame)
{
	printf("raw_frame.len = %d\r\n", raw_frame.len);
	if (raw_frame.len > 0)
	{
		FILE *fp_input = fopen("/userdata/tzw/demo/test/camera_raw_yuv", "w+b");
        if (!fp_input) {
            printf("Can not open input file[/userdata/tzw/cbb_camera/test.jpeg] \r\n");
			return -1;
        }

		int write_len = fwrite(raw_frame.data_addr, 1, raw_frame.len, fp_input);
		if (write_len < 0){
			printf("ret = %d\r\n", write_len);
		}
		return 0;
	}
	
	return 0;
}

int main(int argc, char **argv)
{
	printf("cbb_camera_demo start\r\n");

	//! 打开摄像头
	CameraHandle camera_handle_p;
	camera_handle_p = CbbCameraOpen(CAMERA_DEV_PATH);

	if (camera_handle_p == NULL){
		printf("CbbCameraOpen dev(%s) failed.\r\n", CAMERA_DEV_PATH);
		return -1;
	}
	CbbCameraCtrlDev_t camera_support_fmt = {0};

	//!查询摄像头支持的格式 格式返回需要修改
	int ack = CbbCameraCtrl(camera_handle_p, CBB_CAMERA_ACT_QUE_FMT, &camera_support_fmt);

	//!查询摄像头所有信息 帧率不可查询和设置
	CbbCameraCtrlDev_t camera_que_all = {0};

	ack = CbbCameraCtrl(camera_handle_p, CBB_CAMERA_ACT_QUE_ALL, &camera_que_all);

	//!配置摄像头
	CbbCameraCtrlDev_t camera_ctrl_info = {
		// .camera_ctrl_u.conf_s.format = CBB_CAMERA_FMT_YUV420,
		.camera_ctrl_u.conf_s.format = V4L2_PIX_FMT_NV12,
		.camera_ctrl_u.conf_s.width = 1920,
		.camera_ctrl_u.conf_s.height = 1080,
		.camera_ctrl_u.conf_s.fps = 20 //不支持设置?
	};
	
	ack = CbbCameraCtrl(camera_handle_p, CBB_CAMERA_ACT_SET_CONF, &camera_ctrl_info);

	

	//!初始化编码器
	CbbEncoderConf_t enc_h264_conf = {
		.channel = CBB_ENCODE_CHN_0,
		.width = 1920,
		.height = 1080,
		.in_format = V4L2_PIX_FMT_NV12,
		.out_format = CBB_CAMERA_FMT_H264,
		.rotation = 0,
	};
	CbbEncoderConf_t enc_jpeg_conf = {
		.channel = CBB_ENCODE_CHN_1,
		.width = 1920,
		.height = 1080,
		.in_format = V4L2_PIX_FMT_NV12, //需要符合V4L头文件定义的格式?
		.out_format = CBB_CAMERA_FMT_JPEG, //mpp 8-jpeg 7-h264
		.rotation = 0,
	};
	EncoderHandle encoder_h264_p;
	encoder_h264_p = CbbEncoderInit(enc_h264_conf);
	EncoderHandle encoder_jpeg_p;
	encoder_jpeg_p = CbbEncoderInit(enc_jpeg_conf);

	if (encoder_jpeg_p == NULL )
	{
		printf("CbbEncoderInit failed\r\n");
		return -1;
	}
	
	// //配置开始捕获视频
	CbbCameraCtrlDev_t camera_ctrl_cap = {
		.camera_ctrl_u.action = CBB_CAMERA_START,
	};

	CbbCameraCtrl(camera_handle_p,CBB_CAMERA_ACT_CTL_CAP, &camera_ctrl_cap);

	CbbCameraFrame_t raw_frame;
	CbbEncoderRes_t h264_frame;
	CbbEncoderRes_t jpeg_frame;
	int cnt = 10;

	//打开保存h264文件句柄

	FILE *fp_h264 = fopen(MPI_TEST_OUTPUT_FILE_H264, "w+b");
	if (!fp_h264) {
		printf("Can not open output file[%s] \r\n", MPI_TEST_OUTPUT_FILE_H264);
		return -1;
	}

	while(cnt > 0) {
		if( CBB_CAMERA_ACK_OK == CbbCameraReadFrame(camera_handle_p, &raw_frame, 1000)) {
			//保存一份原始数据
			// save_raw(raw_frame);
			CbbEncoderRun(encoder_h264_p, raw_frame, &h264_frame);//进行H264编码
			CbbEncoderRun(encoder_jpeg_p, raw_frame, &jpeg_frame);//进行jpeg编码
			//处理数据
			process_h264(fp_h264, h264_frame);
			process_jpeg(jpeg_frame);
			CbbCameraRestFrame(camera_handle_p, raw_frame);//!将帧数据重新入队，才能进行下一次的 CbbCameraReadFrame
			// break;
		}
		// cnt--;
	}
	jpeg_index = 0;
	//释放编码器
	CbbEncoderDestroy(encoder_jpeg_p);
	CbbEncoderDestroy(encoder_h264_p);
	//配置停止捕获视频
	CbbCameraCtrlDev_t camera_ctrl_cap_stop = {
		.camera_ctrl_u.action = CBB_CAMERA_STOP,
	};

	CbbCameraCtrl(camera_handle_p,CBB_CAMERA_ACT_CTL_CAP, &camera_ctrl_cap_stop);

	//关闭摄像头
	if (camera_handle_p != NULL){
		CbbCameraClose(camera_handle_p);
		printf("Close Camera!\r\n");
	}
	
	printf("cbb_camera_demo retrun\r\n");
	return 0;
}